﻿Namespace Localization
    <System.Windows.Markup.ContentProperty("ErrorMessages"), ValueConversion(GetType(Exception), GetType(String))>
    Public Class ErrorMessageConverter
        Inherits Freezable
        Implements IValueConverter


        Public Sub New()
            MyBase.New()
            ErrorMessages = New ErrorMessageCollection
        End Sub

        Protected Overrides Function CreateInstanceCore() As System.Windows.Freezable
            Return New ErrorMessageConverter
        End Function

        Private Shared ReadOnly ErrorMessagesPropertyKey As DependencyPropertyKey = DependencyProperty.RegisterReadOnly("ErrorMessages", GetType(ErrorMessageCollection), GetType(ErrorMessageConverter), New PropertyMetadata())
        Public Shared ReadOnly ErrorMessagesProperty As DependencyProperty = ErrorMessagesPropertyKey.DependencyProperty
        Public Property ErrorMessages As ErrorMessageCollection
            Get
                Return GetValue(ErrorMessagesProperty)
            End Get
            Private Set(ByVal value As ErrorMessageCollection)
                SetValue(ErrorMessagesPropertyKey, value)
            End Set
        End Property


        Public Function Convert(value As Object, targetType As System.Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
            Dim result As String = Nothing
            If value IsNot Nothing Then
                For Each em As ErrorMessage In ErrorMessages
                    result = em.GetMessage(value)
                    If result IsNot Nothing Then
                        Exit For
                    End If
                Next
            End If

            Return result
        End Function

        Public Function ConvertBack(value As Object, targetType As System.Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
            Throw New NotSupportedException
        End Function
    End Class

    Public Class ErrorMessage
        Inherits Freezable

        Protected Overrides Function CreateInstanceCore() As System.Windows.Freezable
            Return New ErrorMessage
        End Function

        Public Shared ReadOnly ExceptionProperty As DependencyProperty = DependencyProperty.Register("Exception", GetType(String), GetType(ErrorMessage), New PropertyMetadata("Exception"))
        Public Property Exception As String
            Get
                Return GetValue(ExceptionProperty)
            End Get
            Set(ByVal value As String)
                SetValue(ExceptionProperty, value)
            End Set
        End Property

        Private Shared ReadOnly MessageParserProperty As DependencyProperty = DependencyProperty.Register("MessageParser", GetType(System.Text.RegularExpressions.Regex), GetType(ErrorMessage))
        Private Property MessageParser As System.Text.RegularExpressions.Regex
            Get
                Return GetValue(MessageParserProperty)
            End Get
            Set(ByVal value As System.Text.RegularExpressions.Regex)
                SetValue(MessageParserProperty, value)
            End Set
        End Property


        Public Shared ReadOnly MessageRegExProperty As DependencyProperty = DependencyProperty.Register("MessageRegEx", GetType(String), GetType(ErrorMessage), New PropertyMetadata(AddressOf OnMessageRegExChanged))
        Public Property MessageRegEx As String
            Get
                Return GetValue(MessageRegExProperty)
            End Get
            Set(ByVal value As String)
                SetValue(MessageRegExProperty, value)
            End Set
        End Property
        Private Shared Sub OnMessageRegExChanged(ByVal d As ErrorMessage, ByVal e As DependencyPropertyChangedEventArgs)
            Try
                d.MessageParser = New System.Text.RegularExpressions.Regex(e.NewValue)
            Catch ex As Exception
                d.MessageParser = Nothing
            End Try
        End Sub

        Public Shared ReadOnly FormatProperty As DependencyProperty = DependencyProperty.Register("Format", GetType(String), GetType(ErrorMessage))
        Public Property Format As String
            Get
                Return GetValue(FormatProperty)
            End Get
            Set(ByVal value As String)
                SetValue(FormatProperty, value)
            End Set
        End Property

        Public Function IsMatch(ByVal ex As Exception) As Boolean
            Dim result As Boolean = ex IsNot Nothing
            If result Then
                result = ex.GetType.FullName.EndsWith(Exception)
            End If
            If result And MessageParser IsNot Nothing Then
                result = MessageParser.IsMatch(ex.Message)
            End If
            Return result
        End Function

        Public Function GetMessage(ByVal ex As Exception) As String
            Dim result As String = Nothing
            If IsMatch(ex) Then
                If MessageParser Is Nothing Then
                    result = Format
                Else
                    Dim m As System.Text.RegularExpressions.Match = MessageParser.Match(ex.Message)
                    Dim values() As String = (From g As System.Text.RegularExpressions.Group In m.Groups
                                              Select g.Value).ToArray
                    result = String.Format(Format, values)
                End If
            End If
            Return result
        End Function
    End Class

    Public Class ErrorMessageCollection
        Inherits FreezableCollection(Of ErrorMessage)
    End Class
End Namespace

